local skynet = require "skynet"
local cluster = require "skynet.cluster"
local base = require "base"
local configdao = require "configdao"
local redisdao = require "redisdao"
local filelog = require "filelog"
local filename = "noderequest.lua"
local tabletool = require "tabletool"
local timetool = require "timetool"
local json = require "cjson"
json.encode_sparse_array(true,1,1)

require "pubenum"
require "sssenum"

local noderequest = {
	service = nil,
}

local one_zj_cost = 100


function noderequest.init(service)
	if noderequest.service == nil then
		noderequest.service = service
	end
end

--[[
//创建游戏桌
message createtable {
    optional int32 is_public 		= 1;   		// 是否允许陌生人加入
    optional int32 score_diamond 	= 2;        // 底注
	optional int32 enter_diamond	= 3;		//进桌多少钻石
	optional int32 leave_diamond	= 4;		//离桌多少钻石
	optional int32 table_type 		= 5;		// 创建房间类型(游戏桌类型： 1 系统钻石桌 2 自建钻石桌 3 自建房卡 4 练习桌 5 友豆场)
	optional int32 is_have_joker    = 6;		// 是否开启大小王(百变王牌) 1 不开启 2 开启
	optional int32 max_player_num 	= 7;		// 设置玩家人数(默认5人,可选择5人,7人)
	optional int32 sort_card_times  = 8;		// 理牌时间
	//自建场	
	optional int32	retain_to_num	= 9;		//创建房间局数，只创建自建需要
	optional int32	cost_type		= 10;		//房费花费模式：1 房主自付
}
--]]

function noderequest.createtable(rid, roledata, msgbody)
	local service = noderequest.service
	local responsemsg = {
	}
	if msgbody.table_type == nil then
		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		responsemsg.retstr = "参数不正确"
		return responsemsg
	end
	if msgbody.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
    	if msgbody.score_diamond == nil or msgbody.enter_diamond == nil or msgbody.leave_diamond == nil then
        	responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
        	responsemsg.retstr = "参数不正确"
			filelog.sys_error(" ------create sss room failed-------------")
        	return responsemsg
        end
    elseif msgbody.table_type == SSSTableType.TABLE_TYPE_FANGKA then
    	if msgbody.retain_to_num == nil or msgbody.base_score == nil or msgbody.max_player_num == nil then
    		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
    		responsemsg.retstr = "参数不正确"
			filelog.sys_error(" ------create  sss room failed-------------")
        	return responsemsg
    	end
    elseif msgbody.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
    	if msgbody.score_diamond == nil or msgbody.enter_diamond == nil or msgbody.leave_diamond == nil or msgbody.retain_to_num == nil then
    		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
    		responsemsg.retstr = "参数不正确"
    		filelog.sys_error("-------create zijian zuanshi failed-------", msgbody)
    		return responsemsg
    	end
    end

	if msgbody.max_player_num ~= nil then
		if msgbody.max_player_num ~= SSSPlayerNum.TABLE_PLAYER_NUM_FOUR and msgbody.max_player_num ~= SSSPlayerNum.TABLE_PLAYER_NUM_SEVEN then
			responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
			responsemsg.retstr = "设置玩家人数有误"
			return responsemsg
		end
	end

	----服务器将要维护不能创建游戏
	if service:get_server_flag() then
		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		responsemsg.retstr = "服务器维护中"
		return responsemsg
	end

	local money = roledata.money
	local info = roledata.info

	---如果创建的是房卡模式，那么就要判断房卡是否足够
	if msgbody.table_type == SSSTableType.TABLE_TYPE_FANGKA then
		local need_num = 0
        if msgbody.retain_to_num == 4 then
            need_num = 200
        elseif msgbody.retain_to_num == 8 then
            need_num = 400
        end
		if msgbody.cost_type ~= nil and msgbody.cost_type ~= 1 then
            need_num = math.floor(need_num / msgbody.max_player_num)
        end

        local coin = money.coin
		if not coin or coin < need_num then
            local response = { }
			response.retcode = EErrCode.ERR_NOT_ENOUGH_ROOMCARD
			response.retstr = "金币数量不够！"
			skynet.pcall(skynet.retpack, response)
			return
		end

        if not msgbody.max_player_num 
        or not msgbody.retain_to_num then
            local response = { }
		    response.retcode = EErrCode.ERR_INVALID_PARAMS
		    response.retstr = "创建房间参数错误！"
		    return	response
        end
	---如果创建的是钻石模式，那么就不需要判断房卡是否足够
	elseif msgbody.table_type == SSSTableType.TABLE_TYPE_ZUANSI then


	elseif msgbody.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		if msgbody.retain_to_num <= 0 then
			responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
			responsemsg.retstr = "创建房间局数不合法"
			return responsemsg
		end
		----检查创建者消耗的钻石够不够
		local all_cost = math.floor( msgbody.retain_to_num * one_zj_cost )
		local diamond = money.diamond
		if not diamond or diamond < all_cost then
			responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
			responsemsg.retstr = "创建者zs不够！"
			return responsemsg
		end
	end
	local conf = {
		table_index 	= 0,
		table_type  	= msgbody.table_type,		----游戏桌类型：2 自建房卡桌 1 自建钻石桌
		is_have_joker	= msgbody.is_have_joker or 1,		---是否开启大小王
		sort_cards_time = msgbody.sort_cards_time or 60,	---理牌时间
		max_player_num	= msgbody.max_player_num or SSSPlayerNum.TABLE_PLAYER_NUM_FOUR,	----桌子支持玩家位置数 5人
		retain_to_num	= msgbody.retain_to_num or 10,						----创建房间局数，只创建房卡需要
		cost_type		= msgbody.cost_type or 1,						----房卡花费模式：1 房主自负，2 AA
		base_score      = 0,						----基础分
		max_score       = 0,						----上限分
		is_public	  	= msgbody.is_public,		----是否公开，列表里可以看见（1:公开，0：私密好友）
		score_diamond 	= msgbody.score_diamond,	----底注多少钻石，就是一分多少钻石
		enter_diamond 	= msgbody.enter_diamond,	----进桌多少钻石（客户端计算其实是根据多少分来算的，用户不用随便填写
		leave_diamond 	= msgbody.leave_diamond, 	----离桌多少钻石（计算其实是根据多少分来算的）
		shoot_times		= msgbody.shoot_times or 2,  ----打枪倍数
		shoot_players   = msgbody.shoot_players or 4, ----全垒玩家数
		shoot_players_times = msgbody.shoot_players_times or 2,
		timeout = roledata.table_persist or 10,
		retain_time = roledata.table_persist or 10,	----玩家
		name = roledata.info.rolename .."的房间",
	    create_user_rid = rid,
	    create_user_rolename = roledata.info.rolename,
	    create_user_logo = roledata.info.logo,
	    create_time = timetool.get_time(),
	   	action_timeout = 30,       --玩家出牌时间
		action_timeout_count = 2,
    	common_times  = 1,
    	iscontrol = false,
    	ready_timeout = 10,
		tuoguan_action_time = 2,
		enter_type = 0,
		uuid = "",
		cur_player_num = 0,
		curr_round_code = "----",
		match_type = 0,
		tip_percent = 0,
		is_train_diamond = 0,
		service_fee_rate = 0,
		is_get_service_fee = msgbody.is_get_service_fee,
		poker_num = 1,
		start_player_num = 2,
	}
    if msgbody.is_public == 1 then
        conf.enter_type = SSSTableEnter.TABLE_ENTER_PUBLIC
    else
        conf.enter_type = SSSTableEnter.TABLE_ENTER_PRIVATE
	end
	if msgbody.match_type ~= nil and msgbody.match_type ~= 0 then
		conf.match_type = msgbody.match_type
	end
	if conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
		conf.base_score = 1
	elseif conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		conf.retain_time = 60 * 10
		conf.ready_timeout = 60
	end
	if conf.max_player_num == SSSPlayerNum.TABLE_PLAYER_NUM_FOUR then
		conf.poker_num = 1
		conf.start_player_num = SSSPlayerNum.TABLE_PLAYER_NUM_FOUR
	elseif conf.max_player_num == SSSPlayerNum.TABLE_PLAYER_NUM_SEVEN then
		conf.poker_num = 2
		conf.start_player_num = SSSPlayerNum.TABLE_PLAYER_NUM_SEVEN
	end
	conf.start_player_num = 2
	if conf.is_have_joker ~= 2 then
		conf.is_have_joker = 1
	end

	if conf.is_get_service_fee == nil then
		conf.is_get_service_fee = true
	end
    local result, create_table_id, table_index = service:create_friend_table(conf)
    if not result then
		responsemsg.retcode = EErrCode.ERR_CREATE_TABLE_FAILED
    	responsemsg.retstr = "系统错误，创建朋友桌失败！"
		filelog.sys_error(filename .. "createtable create_friend_table failed")
    else
    	responsemsg.table_index = table_index
		responsemsg.table_code = create_table_id
		responsemsg.nodename = skynet.getenv("nodename")
		---创建自建钻石桌成功,扣钱
		if conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
			local table_service = service.index_to_table[table_index].table_service
			local status, comment = skynet.pcall(skynet.call, table_service, "lua", "get_comment")
			if status then
				local data = {}
				local all_cost = math.floor( msgbody.retain_to_num * one_zj_cost )
				if data[rid] == nil then
					data[rid] = {
						beginvalue = money.diamond,
						value = all_cost,
						endvalue = money.diamond - all_cost,
						rolename = info.rolename,
						real_change = all_cost,
						total_bet = all_cost,
						level = info.level,
					}
				end
				service:game_sub_fangfei(data, comment)
			end
		end
	end
	return responsemsg
end

function noderequest.entertable(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {
		-- -- retcode = EErrCode.ERR_SUCCESS,
	}
	----服务器将要维护不能进入游戏
	if server:get_server_flag() then
		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		responsemsg.retstr = "服务器维护中"
		return responsemsg
	end
	
	local status,is_error = skynet.pcall(cluster.call,"gatenode",".router","check_role_state",rid, 0)
    if not status then
        responsemsg.retcode = EErrCode.ERR_INVALID_TABLE_INDEX
		responsemsg.retstr = "在其他桌内"
        return responsemsg
	end
	if is_error == true then
		responsemsg.retcode = EErrCode.ERR_INVALID_TABLE_INDEX
		responsemsg.retstr = "在其他桌内"
        return responsemsg
	end

	status, is_error = skynet.pcall(cluster.call, "gatenode", ".router", "check_role_inmatch", rid)
	if is_error then
		responsemsg.retcode = EErrCode.ERR_INVALID_TABLE_INDEX
		responsemsg.retstr = "在匹配队列中"
		return responsemsg
	end

	if not server.index_to_table[msgbody.table_index] then
		responsemsg.retcode = EErrCode.ERR_INVALID_TABLE_INDEX
		responsemsg.retstr = "没有找到桌子！"
	else
		local table_service = server.index_to_table[msgbody.table_index].table_service
		local id = server.index_to_table[msgbody.table_index].id
		local ok, result = pcall(skynet.call, table_service, "lua", "entertable", rid, roledata, msgbody)
		responsemsg = result
		if responsemsg.retcode == nil then
			server:forward(rid, table_service, id)
		end
	end
	return responsemsg
end

function noderequest.matchentertable(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {}
	----服务器将要维护不能进入游戏
	if server:get_server_flag() then
		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		responsemsg.retstr = "服务器维护中"
		return responsemsg
	end
	
	if not server.index_to_table[msgbody.table_index] then
		responsemsg.retcode = EErrCode.ERR_INVALID_TABLE_INDEX
		responsemsg.retstr = "没有找到桌子！"
	else
		local table_service = server.index_to_table[msgbody.table_index].table_service
		local id = server.index_to_table[msgbody.table_index].id
		local ok, result = pcall(skynet.call, table_service, "lua", "matchentertable", rid, roledata, msgbody)
		responsemsg = result
		if responsemsg.retcode == nil then
			server:forward(rid, table_service, id)
		end
	end
	return responsemsg
end

function noderequest.gettableconf(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {}

	if not server.index_to_table[msgbody.table_index] then
		responsemsg.retcode = EErrCode.ERR_INVALID_TABLE_INDEX
		responsemsg.retstr = "没有找到桌子!"
		server:notice_tableinfo_togatenode("role_leave_table", rid, skynet.getenv("nodename"), msgbody.table_index)
	else
		local table_service = server.index_to_table[msgbody.table_index].table_service
		local id = server.index_to_table[msgbody.table_index].id
		local ok, result = pcall(skynet.call, table_service, "lua", "gettableconf", rid, roledata, msgbody)
		responsemsg = result
	end
	return responsemsg
end

function noderequest.getpubtablelist(rid)
	local server = noderequest.service
	local list = {
		mylist = {},
		publist = {},
	}
	--获得匹配场信息
	list.matchlist = server.CMD["get_matchlist"]()
	return list
end

function noderequest.destroytable(table_code, table_index)
	local server = noderequest.service
	local id
	if server.code_to_index[table_code] == nil then
		if server.index_to_table[table_index] == nil then 
			return
		else
			local tableservice = server.index_to_table[table_index].table_service
			id = server.index_to_table[table_index].id
			skynet.send(tableservice, "lua", "delete", "forcedeletegm")
			---server.index_to_code[table_index] = nil
		end
	else
		local tableindex = server.code_to_index[table_code]
		if server.index_to_table[tableindex] == nil then
			---server.code_to_index[table_code] = nil 
			return
		else
			local tableservice = server.index_to_table[tableindex].table_service
			id = server.index_to_table[tableindex].id
			skynet.send(tableservice, "lua", "delete", "forcedeletegm") 
		end
	end
	if id then
		server.public_list[id] = nil
		server.my_list[id] = nil
	end
end

function noderequest.matchentertable(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {
		-- -- retcode = EErrCode.ERR_SUCCESS,
	}
	----服务器将要维护不能创建游戏
	if server:get_server_flag() then
		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		responsemsg.retstr = "服务器维护中"
		return responsemsg
	end

	if not server.index_to_table[msgbody.table_index] then
		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		responsemsg.retstr = "没有找到桌子！"
	else
		local table_service = server.index_to_table[msgbody.table_index].table_service
		local id = server.index_to_table[msgbody.table_index].id
		local ok, result = pcall(skynet.call, table_service, "lua", "matchentertable", rid, roledata, msgbody)
		responsemsg = result
		if responsemsg.retcode == nil then
			server:forward(rid, table_service, id)
		end
	end
	return responsemsg
end

function noderequest.gameready(rid, roledata)
	local server = noderequest.service
	local responsemsg = {}
	responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
	responsemsg.retstr = ""
	return responsemsg
end

function noderequest.disconnect(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {}
	server:notice_tableinfo_togatenode("role_leave_table", rid, skynet.getenv("nodename"), 0)
	return responsemsg
end

function noderequest.doaction(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {}
	return responsemsg
end

function noderequest.leavetable(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {}
	server:notice_tableinfo_togatenode("role_leave_table", rid, skynet.getenv("nodename"), 0)
	return responsemsg
end

function noderequest.reentertable(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {}
	responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
	responsemsg.retstr = ""
	server:notice_tableinfo_togatenode("role_leave_table", rid, skynet.getenv("nodename"), 0)
	return responsemsg
end

function noderequest.sitdowntable(rid, roledata, msgbody)
	local server = noderequest.service
	local responsemsg = {}
	responsemsg.retcode = EErrCode.ERR_TABLE_FULL
	responsemsg.retstr = ""
	server:notice_tableinfo_togatenode("role_leave_table", rid, skynet.getenv("nodename"), 0)
	return responsemsg
end

function noderequest.getcoinmatchlist(rid, roledata, msgbody)
	local server = noderequest.service
	local list = {
		mylist = {},
		publist = {},
	}
	--获得匹配场信息
	list.matchlist = server.CMD["get_coinmatchlist"]()
	---filelog.sys_error("------noderequest.getcoinmatchlist------", lists)
	return list
end

----不需要参数
function noderequest.getgamestate()
	local server = noderequest.service
	local playernuminfo = {
		zijian_diamond = 0,
		match_diamond = 0,
		zijian_coin = 0,
		match_coin = 0,
		zijian_fangka = 0,
	}
	playernuminfo.zijian_fangka = server:get_playernum(EGameRoomType.ROOM_TYPE_ZIJIAN_FANGKA)
	playernuminfo.zijian_diamond = server:get_playernum(EGameRoomType.ROOM_TYPE_ZIJIAN_ZUANSI)

	local diamond_matchlist = server.CMD["get_matchlist"]()
	for k, matchlist in pairs(diamond_matchlist) do
		if matchlist.cur_total_player ~= nil then
			playernuminfo.match_diamond = playernuminfo.match_diamond + matchlist.cur_total_player
		end
	end
	
	local coin_matchlist = server.CMD["get_coinmatchlist"]()
	for k, matchlist in pairs(coin_matchlist) do
		if matchlist.cur_total_player ~= nil then
			playernuminfo.match_coin = playernuminfo.match_coin + matchlist.cur_total_player
		end
	end
	playernuminfo.zijian_coin = server:get_playernum(EGameRoomType.ROOM_TYPE_ZIJIAN_COIN)
	---filelog.sys_error("---getgamestate-------dnnode---", playernuminfo)
	return playernuminfo
end

function noderequest.get_matchroom_count()
	local server = noderequest.service
	local diamond_matchlist = server.CMD["get_matchlist"]()
	local match_playernums_info = {}
	for k, matchlist in pairs(diamond_matchlist) do
		if matchlist.match_type then
			if match_playernums_info[matchlist.match_type] == nil then
				match_playernums_info[matchlist.match_type] = {}
			end
			match_playernums_info[matchlist.match_type].match_type = matchlist.match_type
			match_playernums_info[matchlist.match_type].total_player = matchlist.cur_total_player
		end
	end
	return match_playernums_info
end

function noderequest.update_match_playernum()
	local server = noderequest.service
	local diamond_matchlist = server.CMD["get_matchlist"]()
	local match_playernums_info = {}
	for k, matchlist in pairs(diamond_matchlist) do
		if matchlist.match_type then
			if match_playernums_info[matchlist.match_type] == nil then
				match_playernums_info[matchlist.match_type] = {}
			end
			match_playernums_info[matchlist.match_type].match_type = matchlist.match_type
			match_playernums_info[matchlist.match_type].total_player = matchlist.cur_total_player
		end
	end
	local key = "dn_match_playernums_info"
    redisdao.query_data(".gmmqredis", "set", key, json.encode(match_playernums_info))
end

function noderequest.addjackoptnum(childid, moneydata, reason)
	local server = noderequest.service
	local status, result = false, nil
	
	if not status then
		return false
	end
	return result
end

function noderequest.deljackoptnum(childid, moneydata, reason)
	local status, result = false, nil
	if not status then
		return false
	end
	return result
end

function noderequest.getsysperinfo(chargename)
	local status, result = false, nil
	if not status then
		return nil
	end
	return result
end

function noderequest.changesysper(chargename, percent)
	local status, result = false, nil
	if not status then
		return nil
	end
	return result
end

function noderequest.get_tableinfo(table_index, rid)
	local responsemsg = {}
	local server = noderequest.service
	if not server.index_to_table[table_index] then
		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		responsemsg.retstr = "没有找到桌子！"
	else
		local table_service = server.index_to_table[table_index].table_service
		local ok, result = pcall(skynet.call, table_service, "lua", "get_tableinfo", table_index, rid)
		responsemsg = result
	end
	return responsemsg
end

function noderequest.get_alltableinfo()
	local service = noderequest.service
	local all_tableinfo = {
        tableinfos = {},
    }
    for index,item in pairs(service.index_to_table) do
        local status,data = skynet.pcall(skynet.call,item.table_service, "lua", "get_tableinfo")
        if status and data then
            table.insert(all_tableinfo.tableinfos,data)
        end
    end

    --获得匹配场信息
    all_tableinfo.match_infos = service.CMD["get_matchinfo"]()
    all_tableinfo.coinmatch_infos = service.CMD["get_coinmatchinfo"]()
    return all_tableinfo
end

-----GM API----

function noderequest.updata_weight_lists()

end

function noderequest.set_system_lose_limit()

end

function noderequest.set_game_robot_num(base_num, inc_factor, min_num)
	skynet.send(".robotmgr", "lua", "set_game_robot_num", base_num, inc_factor, min_num)
end

function noderequest.set_game_robot_state(is_run)
	skynet.send(".robotmgr", "lua", "set_game_robot_state", is_run)
end

function noderequest.get_game_robot_state()
	return skynet.call(".robotmgr", "lua", "get_game_robot_state")
end

function noderequest.get_game_robot_num()
	return skynet.call(".robotmgr", "lua", "get_game_robot_num")
end

return noderequest